﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace ShiQuan.Security
{
    /// <summary>
    /// 非对称加密的代表算法是RSA算法。
    /// </summary>
    public static class RSASecurity
    {
        #region RSA加密、解密
        
        private static string RSAKey = "ShiQuan$";
        /// <summary>
        /// 生成RSA public key private key
        /// </summary>
        public static void GenerateRSAKey(string privatekeyFile, string publicKeyFile)
        {
            GenerateRSAKey(RSAKey, privatekeyFile, publicKeyFile);
        }
        /// <summary>
        /// 生成RSA public key private key
        /// </summary>
        public static void GenerateRSAKey(string keyContainerName, string privatekeyFile, string publicKeyFile)
        {
            CspParameters param = new CspParameters();
            param.KeyContainerName = keyContainerName;//密匙容器的名称，保持加密解密一致才能解密成功
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(param);
            using (StreamWriter writer = new StreamWriter(privatekeyFile))
            {
                writer.WriteLine(rsa.ToXmlString(true));
            }

            using (StreamWriter writer = new StreamWriter(publicKeyFile))
            {
                writer.WriteLine(rsa.ToXmlString(false));
            }
        }
        /// <summary>
        /// RSA加密
        /// </summary>
        public static string EncryptRSA(this string input)
        {
            return input.EncryptRSA(RSAKey);
        }

        /// <summary>
        /// RSA加密
        /// </summary>
        public static string EncryptRSA(this string input, string keyContainerName)
        {
            CspParameters param = new CspParameters();
            param.KeyContainerName = keyContainerName;//密匙容器的名称，保持加密解密一致才能解密成功
            return input.EncryptRSA(param);
        }

        /// <summary>
        /// RSA加密
        /// </summary>
        public static string EncryptRSA(this string input, CspParameters param)
        {
            if (string.IsNullOrEmpty(input))
            {
                return input;
            }
            try
            {
                using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(param))
                {
                    byte[] plaindata = Encoding.Default.GetBytes(input);//将要加密的字符串转换为字节数组
                    byte[] encryptdata = rsa.Encrypt(plaindata, false);//将加密后的字节数据转换为新的加密字节数组
                    return Convert.ToBase64String(encryptdata);//将加密后的字节数组转换为字符串
                }
            }
            catch
            {
                return input;
            }
        }

        /// <summary>
        /// RSA加密
        /// </summary>
        public static string EncryptRSA(this string input, string publicKey, bool fOAEP = false)
        {
            if (string.IsNullOrEmpty(input))
            {
                return input;
            }
            try
            {
                //publicKey = @"<RSAKeyValue><Modulus>pHfhtj8f/50PMyRq1MjcmbOSvrIIXRihzLTmrZKyo3o9ID6XEc5p4Tyjz9fbwYc8asfAF4GYJ3C/hPLvMST9M9WMKnT+sEsItG6jSVTSM0N580ORIusJRsoVBBgqczr0hNvaGmDxOvGeomqF1P/8tNQzY8L3a/szdrOSa0v6kW0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
                using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
                {
                    rsa.FromXmlString(publicKey);
                    byte[] plaindata = Encoding.Default.GetBytes(input);//将要加密的字符串转换为字节数组
                    byte[] encryptdata = rsa.Encrypt(plaindata, fOAEP);//将加密后的字节数据转换为新的加密字节数组
                    return Convert.ToBase64String(encryptdata);//将加密后的字节数组转换为字符串
                }
            }
            catch
            {
                return input;
            }
        }

        /// <summary>
        /// RSA解密
        /// </summary>
        public static string DecryptRSA(this string input)
        {
            return input.DecryptRSA(RSAKey);
        }

        /// <summary>
        /// RSA解密
        /// </summary>
        public static string DecryptRSA(this string input, string keyContainerName)
        {
            if (string.IsNullOrEmpty(input))
            {
                return input;
            }
            try
            {
                CspParameters param = new CspParameters();
                param.KeyContainerName = keyContainerName;
                using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(param))
                {
                    byte[] encryptdata = Convert.FromBase64String(input);
                    byte[] decryptdata = rsa.Decrypt(encryptdata, false);
                    return Encoding.Default.GetString(decryptdata);
                }
            }
            catch
            {
                return input;
            }
        }
        /// <summary>
        /// RSA解密
        /// </summary>
        public static string DecryptRSA(this string input, string privateKey, bool fOAEP = false)
        {
            if (string.IsNullOrEmpty(input))
            {
                return input;
            }
            try
            {
                using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
                {
                    rsa.FromXmlString(privateKey);
                    byte[] encryptdata = Convert.FromBase64String(input);
                    byte[] decryptdata = rsa.Decrypt(encryptdata, fOAEP);
                    return Encoding.Default.GetString(decryptdata);
                }
            }
            catch
            {
                return input;
            }
        }
        #endregion
    }
}
